#!/usr/bin/env bash
# Portions Copyright (c) 2005-2007  WyldRyde IRC Network
# Copyright (c) 2009 GeekShed Ltd.
# All rights reserved.
#
# $Id$
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

for script in `pwd`/include/*
do
	. ${script}
done

conf_init

WORKDIR=`pwd`
COMMAND=`basename $0`

check_config() {
	if [ "${1}" = "" ] ; then
		# using conf/network.conf to write to
		CONFFILE="${WORKDIR}/conf/network.conf"
	else
		CONFFILE="${WORKDIR}/conf/${1}"
		if [ ! -e ${CONFFILE} ] ; then
			echo "ERROR: ${WORKDIR}/conf/${1} doesn't exist, aborting"
			exit
		fi
	fi
	echo ${CONFFILE}
}

add_server() {
	check_config $1
}

create_config() {
	if [ "${1}" = "" ] ; then
		if [ "${CONFFILE}" = "" ] ; then
			echo "ERROR: must specify a config file!"
			exit
		fi
	else
		CONFFILE="${WORKDIR}/conf/${1}"
		if [ -e ${CONFFILE} ] ; then
			echo "ERROR: config file already exists!"
			exit
		fi
	fi

	
}
prime_server() {
        ossh ${1} "rm -rf ${NETSHORTNAME}-data/ && mkdir -p ${NETSHORTNAME}-data/logs/ && mkdir ${NETSHORTNAME}-data/${NETSHORTNAME}-ircd/ && touch ${NETSHORTNAME}-data/logs/unreal.log && touch ${NETSHORTNAME}-data/local.conf"
        cd ${WORKDIR}/certs/ && tar -cpvf - *.pem | bzip2 | ossh ${1} "bunzip2 | tar -xpf - -C ./${NETSHORTNAME}-data"
	script_sync "${1}"
}
push_key() {
        ossh ${1} 'if [ ! -d ~/.ssh/ ]; then mkdir ~/.ssh/; fi; chmod -R 0700 ~/.ssh/'
        cat ~/.ssh/id_rsa.pub | ossh ${1} 'cat >> ~/.ssh/authorized_keys'
}
push_bins() {
	SVNPATH="${2}"
	SERVER="$( echo ${1} | cut -d : -f 2)"
	SERVERCLASS="$( echo ${1} | cut -d : -f 12)"
	if [ "${SERVERCLASS}" = "" ] ; then
		SERVERCLASS="default"
	fi
	SERVERPWD="$(ossh ${SERVER} pwd)"
	FLAGS="$( echo ${1} | cut -d : -f 5)"
	cd ${SVNPATH}/${SERVERCLASS} && tar -cpf - ${NETSHORTNAME}-ircd | bzip2 | ossh "${SERVER}" "nohup ${NETSHORTNAME}-data/scripts/run.sh >${NETSHORTNAME}-data/logs/build.log" "build" "${NETSHORTNAME}" "${FLAGS}"
	mkdir -p /tmp/binbackup/
	ossh ${SERVER} "tar -cpf - ${NETSHORTNAME}-ircd | bzip2" > /tmp/binbackup/${SERVER}.tar.bz2
}
push_server() {
	rm -rf ${OUTPUTPATH}/svn

	if [ "${1}" = "" ] ; then
		for WORKINGSERVERS in `grep ^S ${STRIPCONF}`
		do
			SERVERLINE=`echo ${WORKINGSERVERS}`
			CLASS="$(echo "${SERVERLINE}" | cut -d : -f 12)"
			fetch_source "${OUTPUTPATH}/svn" "${CLASS}"
			push_bins "${SERVERLINE}" "${OUTPUTPATH}/svn"
		done
	else
		WORKINGSERVERS=`grep ^S ${STRIPCONF} | grep ^S:${1}`
		SERVERLINE=`echo ${WORKINGSERVERS}`
		CLASS="$(echo "${SERVERLINE}" | cut -d : -f 12)"
		fetch_source "${OUTPUTPATH}/svn" "${CLASS}"
		push_bins "${SERVERLINE}" "${OUTPUTPATH}/svn"
	fi
}

fetch_source() {
	SRCDIR="${1}"
	if [ "${2}" = "" ] ; then
		CLASSNAME="default"
	else
		CLASSNAME="${2}"
	fi
	mkdir -p "${SRCDIR}/${CLASSNAME}"
	cd "${SRCDIR}/${CLASSNAME}"
	if [ "${CLASSNAME}" = "default" ] ; then
		ILINE="$(grep ^I:: ${STRIPCONF})"
	else
		ILINE="$(grep ^I:${CLASSNAME}: ${STRIPCONF})"
	fi

	if [ "${ILINE}" = "" ] ; then
		URL="http://gs-ircd.googlecode.com/svn/branches/1.0-STABLE"
	else
		URL="$(echo "${ILINE}" | head -n 1 | cut -d : -f 4-200)"
	fi
	svn checkout "${URL}" "${NETSHORTNAME}-ircd"
	ERRCODE="$?"
	if [ "${ERRCODE}" != "0" ] ; then
		mkdir -p "${NETSHORTNAME}-ircd"
		if [ -f "${WORKDIR}/cache/${CLASSNAME}.tar" ] ; then
			tar -xvpf "${WORKDIR}/cache/${CLASSNAME}.tar" -C "${NETSHORTNAME}-ircd"
		else
			exit
		fi
	fi
}

backup_module() {
	ossh ${1} tar -cpf - ${2} >${BACKUPPATH}/${1}/${2}.tar 2>/dev/null
}
backup_sys() {
	BACKUPPATH=${HOME}/back/$(rand)
	mkdir -p ${BACKUPPATH}
	DATE=`date +%Y%m%d%H%M`
	echo "${DATE}=${BACKUPPATH}" >> ${HOME}/back/back.log
        for WORKINGSERVERS in `grep ^S ${STRIPCONF}`
        do
            SERVER=`echo ${WORKINGSERVERS} | cut -d : -f 2`
	    mkdir -p ${BACKUPPATH}/${SERVER}
            backup_module ${SERVER} ${NETSHORTNAME}-ircd
            backup_module ${SERVER} ${NETSHORTNAME}-config
            backup_module ${SERVER} .ssh
            backup_module ${SERVER} bopm
            backup_module ${SERVER} services
            backup_module ${SERVER} ${NETSHORTNAME}-data
        done
	tar -cf ${BACKUPPATH}/home.tar -x back /home/wamphyre/* /home/wamphyre/.*
	tar -cf ${BACKUPPATH}/local.tar /usr/local/*
	tar -cf ${HOME}/back/${DATE}.tar ${BACKUPPATH}/*
	bzip2 ${HOME}/back/${DATE}.tar

}
ping() {
	for WORKINGSERVERS in `grep ^S ${STRIPCONF}`
	do
		SERVER=`echo ${WORKINGSERVERS} | cut -d : -f 2`
#		echo "${SERVER}: `ossh ${SERVER} uname -sr 2>/dev/null` `ossh ${SERVER} openssl version 2>/dev/null` `ossh ${SERVER} gcc --version 2>/dev/null | head -n 1 ` `ossh ${SERVER} "grep MAXCONNECTIONS ${NETSHORTNAME}-ircd/config.log | head -n 1"` "
#		ossh "${SERVER}" strings "${NETSHORTNAME}-ircd/src/ircd" \| grep -- -gs
	ossh "${SERVER}" grep therock /etc/passwd
	done
}
version() {
	for WORKINGSERVERS in `grep ^S ${STRIPCONF}`
	do
		SERVER=`echo ${WORKINGSERVERS} | cut -d : -f 2`
		echo "${SERVER}: " `ossh "${SERVER}" strings "${NETSHORTNAME}-ircd/src/ircd" \| grep -- -gs \| head -n 1`
	done
}
dump_list() {
	for WORKINGSERVERS in `grep ^S ${STRIPCONF}`
	do
		SERVER=`echo ${WORKINGSERVERS} | cut -d : -f 2`
		echo ${SERVER}
		for USERS in `grep ^U ${STRIPCONF}`
		do
			case `echo ${USERS} | cut -d : -f 5` in
				*g*)
					DROPIT=y	
				;;
				*r*)
					DROPIT=y
				;;
				*)
					DROPIT=n
				;;
			esac
			if [ "${DROPIT}" != "y" ] ; then
				for servern in `echo ${USERS} | cut -d : -f 6 | sed s/\-/\ /g`
				do
					if [ "` echo ${servern} | cut -d @ -f 2`" = "${SERVER}" ] ; then
						echo "    `echo ${servern} | cut -d @ -f 1`=`echo ${USERS} | cut -d : -f 3 | sed s/\_/\ /g` <`echo ${USERS} | cut -d : -f 2`>"
					fi
				done
			fi
		done
        done
	
}

rehash_list() {
	export MSERVERNAME="$1"
	mcommand "cd ${NETSHORTNAME}-ircd && ./unreal rehash"
}

restart_list() {
	export MSERVERNAME="$1"
	mcommand "cd ${NETSHORTNAME}-ircd && ./unreal restart"
}
stop_list() {
	export MSERVERNAME="$1"
	mcommand "cd ${NETSHORTNAME}-ircd && ./unreal stop"
}
start_list() {
	export MSERVERNAME="$1"
	mcommand "cd ${NETSHORTNAME}-ircd && ./unreal start"
}

checkdef() {
	export MSERVERNAME="$1"
	mcommand "command -v nohup"
}

script_sync() {
	OLDPWD="$(pwd)"
	cd "${WORKDIR}"
	if [ "${1}" = "" ] ; then
		for WORKINGSERVERS in `grep ^S ${STRIPCONF} | awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }'`
		do
			SERVER=`echo ${WORKINGSERVERS} | cut -d : -f 2`
			echo ${SERVER}
			tar -cf - scripts | ossh ${SERVER} "rm -rf ./${NETSHORTNAME}-data/scripts && tar -xpf - -C ./${NETSHORTNAME}-data" 2>/dev/null
		done
	else
		echo "${1}"
		tar -cf - scripts | ossh "${1}" "rm -rf ./${NETSHORTNAME}-data/scripts && tar -xpf - -C ./${NETSHORTNAME}-data" 2>/dev/null
	fi
	cd "${OLDPWD}"
}

mcommand() {
	if [ "${MSERVERNAME}" = "" ] ; then
		for WORKINGSERVERS in `grep ^S ${STRIPCONF} | awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }'`
		do
			SERVER=`echo ${WORKINGSERVERS} | cut -d : -f 2`
			echo ${SERVER}
			ossh ${SERVER} "$*"
		done
	else
		echo ${MSERVERNAME}
		ossh ${MSERVERNAME} "$*"
	fi
}
add_server() {
	ossh ${1} mkdir -p ${NETSHORTNAME}-data/${NETSHORTNAME}-ircd
	ossh ${1} mkdir -p ${NETSHORTNAME}-ircd
}
usage() {
	echo "usage:"
	echo "    ${COMMAND} push"
	echo "    ${COMMAND} create"
	echo "    ${COMMAND} add"
	echo "    ${COMMAND} backup"
	echo "    ${COMMAND} ping"
	echo "    ${COMMAND} dump"
	echo "    ${COMMAND} rehash"
        echo "    ${COMMAND} prime"
        echo "    ${COMMAND} pushkey"
        echo "    ${COMMAND} makemodules"
}



case "${1}" in
	[pP][uU][sS][hH]) 
		check_config
		push_server $2
	;;
        [pP][uU][sS][hH][kK][eE][yY])
                push_key $2
        ;;
	[aA][dD][dD])
		add_server $2
	;;
	[cC][rR][eE][aA][tT][eE])
		create_config $2
	;;
	[bB][aA][cC][kK][uU][pP])
		backup_sys $2
	;;
	[pP][iI][Nn][Gg])
		ping $2
	;;
	[vV][eE][rR][sS][iI][oO][nN])
		version $2
	;;
	[dD][uU][mM][pP])
		dump_list
	;;
        [pP][rR][iI][mM][eE])
                prime_server $2
        ;;
        [mM][aA][kK][eE][mM][oO][dD][uU][lL][eE][sS])
                make_modules $2
        ;;
	[rR][eE][hH][aA][sS][hH])
		rehash_list $2
	;;
	[cC][hH][eE][cC][kK][dD][eE][fF])
		checkdef $2
	;;
	[rR][eE][sS][tT][aA][rR][tT])
		restart_list $2
	;;
	[sS][cC][rR][iI][pP][tT][sS][yY][nN][cC])
		script_sync $2
	;;
	[sS][tT][oO][pP])
		stop_list $2
	;;
	[sS][tT][aA][rR][tT])
		start_list $2
	;;
	*)
		usage
	;;
esac

chmod -R a+w "${OUTPUTPATH}"
rm -r "${OUTPUTPATH}"
